import os
from pathlib import Path

class FileCounter:
    def __init__(self):
        self.supported_extensions = {
            '.py', '.java', '.cpp', '.c', '.h', '.hpp', '.cs', '.js', '.ts',
            '.html', '.css', '.xml', '.json', '.md', '.txt', '.sql', '.php',
            '.rb', '.go', '.rs', '.swift', '.kt', '.scala', '.sh', '.bat',
            '.ps1', '.vbs', '.lua', '.pl', '.r', '.m', '.f90', '.f95', '.f03',
            '.f08', '.f', '.for', '.f77', '.f66', '.fpp', '.f90', '.f95',
            '.f03', '.f08', '.f', '.for', '.f77', '.f66', '.fpp'
        }
        
    def count_files(self, paths, recursive=True):
        """统计文件数量和代码行数
        
        Args:
            paths: 文件或文件夹路径列表
            recursive: 是否递归统计子文件夹
            
        Returns:
            list of tuples: [(path, file_count, line_count, total_lines), ...]
        """
        results = []
        for path in paths:
            if os.path.isfile(path):
                # 如果是文件，直接统计
                file_count, line_count, total_lines = self._count_single_file(path)
                results.append((path, file_count, line_count, total_lines))
            elif os.path.isdir(path):
                # 如果是文件夹，统计文件夹内所有文件
                file_count, line_count, total_lines = self._count_directory(path, recursive)
                results.append((path, file_count, line_count, total_lines))
        return results
        
    def _count_single_file(self, file_path):
        """统计单个文件的行数"""
        try:
            with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
                lines = f.readlines()
                total_lines = len(lines)
                code_lines = sum(1 for line in lines if line.strip() and not line.strip().startswith('#'))
                return 1, code_lines, total_lines
        except Exception as e:
            print(f"Error counting file {file_path}: {str(e)}")
            return 1, 0, 0
            
    def _count_directory(self, dir_path, recursive=True):
        """统计文件夹内所有文件的行数"""
        total_files = 0
        total_code_lines = 0
        total_lines = 0
        
        try:
            for root, _, files in os.walk(dir_path):
                if not recursive and root != dir_path:
                    continue
                    
                for file in files:
                    file_path = os.path.join(root, file)
                    if os.path.isfile(file_path):
                        ext = os.path.splitext(file)[1].lower()
                        if ext in self.supported_extensions:
                            file_count, code_lines, lines = self._count_single_file(file_path)
                            total_files += file_count
                            total_code_lines += code_lines
                            total_lines += lines
                            
        except Exception as e:
            print(f"Error counting directory {dir_path}: {str(e)}")
            
        return total_files, total_code_lines, total_lines
        
    def get_directory_contents(self, dir_path, recursive=True):
        """获取文件夹内容，并递归统计每个文件夹下所有文件和子文件夹的统计信息
        Args:
            dir_path: 文件夹路径
            recursive: 是否递归获取子文件夹内容
        Returns:
            list of tuples: [(path, is_dir, file_count, line_count, total_lines, relative_path), ...]
        """
        contents = []
        def _walk(current_path, rel_path):
            file_count = 0
            code_lines = 0
            total_lines = 0
            sub_items = []
            try:
                with os.scandir(current_path) as it:
                    for entry in sorted(it, key=lambda e: e.name):
                        entry_rel_path = os.path.join(rel_path, entry.name)
                        full_path = entry.path
                        if entry.is_dir():
                            # 递归统计子文件夹
                            sub_file_count, sub_code_lines, sub_total_lines, sub_sub_items = _walk(full_path, entry_rel_path)
                            sub_items.append((full_path, True, sub_file_count, sub_code_lines, sub_total_lines, entry_rel_path))
                            sub_items.extend(sub_sub_items)
                            file_count += sub_file_count
                            code_lines += sub_code_lines
                            total_lines += sub_total_lines
                        elif entry.is_file():
                            ext = os.path.splitext(entry.name)[1].lower()
                            if ext in self.supported_extensions:
                                f_count, c_lines, t_lines = self._count_single_file(full_path)
                                sub_items.append((full_path, False, f_count, c_lines, t_lines, entry_rel_path))
                                file_count += f_count
                                code_lines += c_lines
                                total_lines += t_lines
                            else:
                                sub_items.append((full_path, False, 1, 0, 0, entry_rel_path))
                                file_count += 1
            except Exception as e:
                print(f"Error getting directory contents {current_path}: {str(e)}")
            return file_count, code_lines, total_lines, sub_items
        # 统计当前文件夹
        total_files, total_code_lines, total_lines, all_items = _walk(dir_path, "")
        # 当前文件夹本身
        contents.append((dir_path, True, total_files, total_code_lines, total_lines, ""))
        # 其下所有内容
        contents.extend(all_items)
        return contents 